from popen2 import popen2

class TremMessage:
	#cmd -> to function
	#time
	#slot
	#guid
	#name
	#oldname # if renamed
	#ip
	#oldteam
	#team
	#ping
	#weapon
	#textmsg
	def __init__(self):
		self.cmd=None
		self.time=None
		self.slot=None
		self.guid=None
		self.name=None
		self.oldname=None
		self.ip=None
		self.oldteam=None
		self.team=None
		self.ping=None
		self.weapon=None
		self.textmsg=None
	

class TremListener:
	# player
	def ClientConnect(self, msg):
		# slot [ip] (guid) "name"
		pass
	def ClientDisconnect(self, msg):
		# slot  [ip] (guid) "name"
		pass
	def ClientRename(self, msg):
		# slot [ip] (guid) "name" -> "name2"
		pass	
	def ClientBegin(self, msg):
		# slot
		pass
	def ClientTeam(self, msg):
		# name joined the humans
		# name left the aliens
		pass
	def ClientTeamClass(self, msg):
		# slot human ckit
		# slot alien level0
		pass
	def Decon(self, msg):
		# 3 9 0: msg
		pass
	def Build(self, msg):
		# 3 9 0: msg
		pass
	def Kill(self, msg):
		# 1 2 4: msg
		pass
	def score(self, msg):
		# kills ping: 73 client: 1 name
		pass
	def say(self, msg):
		# info structure
		pass
	def sayteam(self, msg):
		# name: msg
		pass
	
	# Special events
	def Stage(self, msg):
		# A 2: alien reached Stage 2
		pass
	def Exit(self):
		# Humans win.
		pass
	def ShutdownGame(self, msg):
		# no arguments
		pass
	def InitGame(self, msg):
		pass
	def RealTime(self, msg):
		# YYYY/mm/dd hh:mm:ss
		pass
	def Admin_Command(self, msg):
		# name: command
		pass
	
class TremParser:
	def __init__(self):
		self.reset()
		self.resetListeners()
	def reset(self):
		#self.players=[(None,)*100]
		pass
	
	def parse_slotipguidname(self, m):
		t=m.split(' ');
		slot=int(t[0])
		ip=t[1].strip('[]');
		guid=t[2].strip('()');
		name=' '.join(t[3:]).strip('"')
		return (slot, ip, guid, name)
	def parse_clientteamclass(self, m):
		t=m.split(' ')
		return (int(t[0]),t[1],t[2])
			
	def parse_slotipguidnameoldname(self, m):
		t=m.split(' ');
		slot=int(t[0])
		ip=t[1].strip('[]');
		guid=t[2].strip('()');
		t=(' '.join(t[3:])).split('->')
		print (t)
		oldname=t[0].strip('"')
		name=t[1].strip('"')
		return (slot, ip, guid, name, oldname)
	
	def parse_slotvictimweapontextmsg(self, m):
		t=m.split(':');
		t2=t[0].split(' ')
		return (int(t2[0]), int(t2[1]), int(t2[2]), ':'.join(t[1:]))
		
	def parse_nametextmsg(self, m):
		t=m.split(':')
		name=t[0]
		textmsg=':'.join(t[1:])
		return (name, textmsg)
		
	def parseLine(self, l):
		m=TremMessage()
		#print (l)
		rdate=l[:7]
		m.cmd=(l[7:].split(':')[0])
		rest=(':'.join(l[7:].split(':')[1:])).strip()
		if(m.cmd=='ClientConnect'):
			m.slot,m.ip,m.guid,m.name=self.parse_slotipguidname(rest)
		elif(m.cmd=='ClientDisconnect'):
			m.slot,m.ip,m.guid,m.name=self.parse_slotipguidname(rest)
		elif(m.cmd=='ClientBegin'):
			m.slot=rest
		elif(m.cmd=='ClientRename'):
			m.slot,m.ip,m.guid,m.name,m.oldname=self.parse_slotipguidnameoldname(rest)
		elif(m.cmd=='ClientTeam'):
			m.name, m.textmsg=self.parse_nametextmsg(rest)
		elif(m.cmd=='say'):
			m.name, m.textmsg=self.parse_nametextmsg(rest)
		elif(m.cmd=='sayteam'):
			m.name, m.textmsg=self.parse_nametextmsg(rest)
		elif(m.cmd=='Kill'):
			m.slot, m.victim, m.weapon, m.textmsg=self.parse_slotvictimweapontextmsg(rest)
		elif(m.cmd=='Build' or m.cmd=='Decon'):
			m.slot, m.struct, m.weapon, m.textmsg=self.parse_slotvictimweapontextmsg(rest)
		elif(m.cmd=='ClientTeamClass'):
			m.slot, m.team, m.weapon = self.parse_clientteamclass(rest)
		#print(m.cmd)
		self.sendMessage(m)
		
			
	def resetListeners(self):
		self.listeners=[]
	
	def sendMessage(self, msg):
		for l in self.listeners:
			if hasattr(l, msg.cmd):
				c=getattr(l, msg.cmd)
				if(callable(c)):
					c(msg)
					
	def addListener(self, listener):
		self.listeners.append(listener)
		

class TremParserSocket(TremParser):
	def __init__(self):
		pass
		
class TremParserLog(TremParser):
	def __init__(self, logfile):
		self.logfile=logfile
		self.f=None
		self.is_running=False
		self.__openlog()
		TremParser.__init__(self)
		
	def __openlog(self):
		if self.f is None:
			#self.f,w=popen2("tail -fn50 %s" % (self.logfile))
			self.f,w=popen2("cat %s" % (self.logfile))
		
	def __closelog(self):
		if self.f is not None:
			self.f.close()
			self.f=None
		
	def run(self):
		self.__openlog()
		self.is_running=True
		while(self.is_running):
			l=self.f.readline()
			self.parseLine(l)
		
	def stop():
		self.is_running=False
